package com.ocp.macro.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ocp.macro.entity.*;
import com.ocp.macro.enums.DataCode;
import com.ocp.macro.exception.MysqlException;
import com.ocp.macro.mapper.dealer.DealListMapper;
import com.ocp.macro.mapper.dealerAccount.DealerAccountMapper;
import com.ocp.macro.service.DealerListService;
import com.ocp.macro.utils.GsonUtils;
import com.ocp.macro.annotation.AutowireUserToken;
import com.ocp.macro.entity.UserInfoToken;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

import java.util.HashMap;
import java.util.Map;

/**
 * @author 孙历
 * @version 0.1
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class DealListServiceImpl implements DealerListService {
    //redis缓存注入
    @Resource
    RedisTemplate<String,Object> redisTemplate;
    @Resource
    DealListMapper dealListMapper;
    @Resource
    DealerAccountMapper dealerAccountMapper;
    /**
     * 实现：孙历
     * 请求经销商收货信息和经销商信息
     * @return
     */
    @Override
    @AutowireUserToken
    public String dealerInfo(UserInfoToken userInfoToken) {
        DealList dealList=new DealList();//实例化
        Map<String,Object> map=new HashMap<String, Object>(); //用map封装实体类的键值对
        Integer dealAccountId=userInfoToken.getUserId();//获取经销商账号ID
        List<String> dealno=dealListMapper.dealerAccList(dealAccountId);//通过经销商账户ID获取关联表的经销商编号集合
        if(dealno.size()==0){//判断经销商ID是否关联经销商信息
            DataCode.NO_USER_MESSAGE.setMessage("该用户未关联经销商信息");
            map.put("message",DataCode.NO_USER_MESSAGE.getMessage());//返回message信息
            map.put("code",DataCode.NO_USER_MESSAGE.getCode());//返回状态码
        }else {
            dealList.setDealerAccountId(dealAccountId);//设置查询条件
            List<DealList> dealerinfo=dealListMapper. getDealerListInfoByDealerAccountId(dealList); //获取经销商信息
            List<Address> addresses=dealListMapper.addressInfo(dealAccountId);//根据经销商ID获取收货信息
            map.put("dealerInfo", dealerinfo);//封装经销商信息
            map.put("address",addresses);//封装收货信息

            map.put("code",DataCode.SUCCESS.getCode());//返回状态码
            map.put("message",DataCode.SUCCESS.getMessage());//返回message信息
        }

        return GsonUtils.toJson(map);//返回键值对用JSON切面类处理
    }

    /**
     * 设计：孙历
     * 验证旧密码
     * @param oldpassword
     * @param userInfoToken
     * @return
     */
    @Override
    @AutowireUserToken
    public String checkOldPassword(String oldpassword, UserInfoToken userInfoToken) {
        Map<String,Object> map = new HashMap<>();//map集合存放返回信息
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();//切面类，对密码进行处理
        String oldpwd=dealListMapper.checkOldPassword(userInfoToken.getUserId());//获取账号的旧密码
        Boolean flag=encoder.matches(oldpassword,oldpwd);//判断密码是否相同
        if(flag==true){
            map.put("code",DataCode.SUCCESS.getCode());
            map.put("message",DataCode.SUCCESS.getMessage());
        }else{
            map.put("code",DataCode.FAIL.getCode());
            map.put("message",DataCode.FAIL.getMessage());
        }
        return GsonUtils.toJson(map);
    }

    /**
     * 实现：孙历
     * 经销商修改密码
     * @param newpassword
     * @return
     */
    @Override
    @AutowireUserToken
    public String modifyPassword(String newpassword, UserInfoToken userInfoToken) {
        Map<String,Object> map=new HashMap<>();//用map保存更改结果
        Integer dealAccountId = userInfoToken.getUserId();//获取token里存放的经销商账户ID
        DealerAccount dealerAccount=new DealerAccount();//用对象保存账号ID和新密码
        dealerAccount.setDealAccountId(dealAccountId);//存放账号ID
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        String encode = encoder.encode(newpassword);//密码加密
        dealerAccount.setDealPwd(encode);//存放加密后的新密码
        Integer flag=dealListMapper.modifyPwd(dealerAccount);//调用Mapper更改
        if(flag!=1){
            map.put("code",DataCode.FAIL.getCode());//返回失败状态码
            map.put("message",DataCode.FAIL.getMessage());//返回失败message信息
        }else{
            DealerAccount account = dealerAccountMapper.selectDealerAccountOne(dealerAccount);//查询账户信息
            Set<String> keys = redisTemplate.keys(account.getUserName()+"*");//查询缓存里的账户token信息
            if (keys!=null) {
                redisTemplate.delete(keys);// 清除缓存里的账户有关信息
            }
            map.put("code",DataCode.SUCCESS.getCode());//返回成功状态码
            map.put("message",DataCode.SUCCESS.getMessage());//返回成功message信息
        }
        return GsonUtils.toJson(map);//返回结果用JSON处理
    }

    /**
     * 实现：孙历
     * 查看经销商账号关联的客户信息
     * @param userInfoToken
     * @return
     */
    @Override
    @AutowireUserToken
    public String customerInfo(UserInfoToken userInfoToken) {
        Map<String,Object> map = new HashMap<>();
        Integer dealAccountId = userInfoToken.getUserId();//获取token里存放的经销商账户ID
        List<Integer> custId=dealListMapper.dealAccCust(dealAccountId);//通过经销商账户ID获取关联表客户ID
        if(custId.size()==0||custId==null){
            DataCode.NO_USER_MESSAGE.setMessage("未关联客户信息");
            map.put("code",DataCode.NO_USER_MESSAGE.getCode());
            map.put("message",DataCode.NO_USER_MESSAGE.getMessage());
        }else{
            List<CustomerList> customerLists=dealListMapper.cusInfo(custId);//通过客户信息ID集合获取客户信息
            map.put("code",DataCode.SUCCESS.getCode());
            map.put("message",DataCode.SUCCESS.getMessage());
            map.put("custinfo",customerLists);
        }
        return GsonUtils.toJson(map);//结果集通过JSON格式化返回
    }

    @Override
    @Cacheable(cacheNames = "dealListInfo", key = "#dealList")
    public String getDealerListInfo(DealList dealList) {
        PageHelper.startPage(dealList.getPage(), dealList.getRows());
        List<DealList> list = dealListMapper.getDealerListInfoByDealerAccountId(dealList);
        PageInfo<DealList> pageInfo = new PageInfo<>(list);
        Map<String, Object>  map = new HashMap<>();
        map.put("data", pageInfo.getList()); // 当前页数据
        pageInfo.setList(null);
        map.put("pageInfo", pageInfo); // 分页信息
        map.put("code", DataCode.SUCCESS.getCode());
        map.put("message", DataCode.SUCCESS.getMessage());

        return GsonUtils.toJson(map);
    }

    @Override
    @CacheEvict(cacheNames = "dealListInfo", allEntries = true)
    public String setDealerAccountRelationDealerInfo(String jsonStr) {
        JSONObject jsonObject = GsonUtils.toJsonObject(jsonStr);

        log.debug(jsonObject.toString());

        if (jsonObject.get("dealRelNos")==null || jsonObject.get("dealerId")==null || jsonObject.get("state")==null)
            throw new RuntimeException("参数信息不能为空！");
        if (jsonObject.getInteger("state").equals(0)){ // 解除关联关系
            Integer dealerId = jsonObject.getInteger("dealerId");
            List<String> dealRelNos = Collections.singletonList(jsonObject.getString("dealRelNos"));
            Integer count = dealListMapper.updateDealerListState(dealRelNos, 1); // 更新状态，该经销商信息未任何关联
            if (count!=null && count > 0){
                count = dealListMapper.deleteDealerAccountRelDealListInfo(dealerId, jsonObject.getString("dealRelNos"));
                if (count==null || count<=0)
                    throw new RuntimeException("删除经销商信息关联记录出错");
            }else{
                throw new RuntimeException("更新经销商信息状态出错");
            }
        }else if(jsonObject.getInteger("state").equals(2)){ // 设置关联关系
            List<String> realerNos = Collections.singletonList(jsonObject.getString("dealRelNos"));

            DealList dealList = new DealList();
            dealList.setDealNo(jsonObject.getString("dealRelNos"));
            dealList.setStatus(1);

            List<DealList> list = dealListMapper.getDealerListInfoByDealerAccountId(dealList);
            if (list==null || list.size()==0)
                throw new RuntimeException("该经销商信息已经其它账号被关注或不存在或被禁用中");

            Integer count = dealListMapper.updateDealerListState(realerNos, 2);// 更新状态，即该经销商信息已被关联
            if (count==null || count==0)
                throw new MysqlException(DataCode.MODIFY_EXCEPTION);

            count = dealListMapper.addDealerAccountListRel(realerNos, jsonObject.getInteger("dealerId"));
            if (count==null || count==0)
                throw new MysqlException(DataCode.MODIFY_EXCEPTION);
        }else{
            throw new RuntimeException("错误参数信息！");
        }

        Map<String, Object> map = new HashMap<>();
        map.put("code", DataCode.SUCCESS.getCode());
        map.put("message", DataCode.SUCCESS.getMessage());

        return GsonUtils.toJson(map);
    }




}
